#pragma once
#include "Socket.hpp"
#include <iostream>
#include <pthread.h>
#include <functional>

// using func_t = std::function<void(Socket*)>;
using func_t = std::function<std::string(std::string &)>;

class TcpServer;
class ThreadData
{
public:
    ThreadData(Socket *socket, TcpServer *tcp)
        : _socket(socket), _this(tcp)
    {
    }

public:
    Socket *_socket;
    TcpServer *_this;
};

class TcpServer
{
public:
    TcpServer(uint16_t port, func_t func)
        : _port(port), _listensocket(new TcpSocket()), _handler_request(func)
    {
        _listensocket->BuildListenSocket(_port, backlog);
    }

    static void *ThreadRoutine(void *args)
    {
        pthread_detach(pthread_self());

        ThreadData *td = static_cast<ThreadData *>(args);
        // td->_this->_handler_request(td->_socket);
        std::string http_response;

        // 接收package
        //  std::cout << "instream" << std::endl;
        if (td->_socket->Recv(&http_response, 1024))
        {
            // std::cout << instream << std::endl;            //DEBUG
            // 处理package
            // std::cout << "s_send" << std::endl;             //DEBUG
            std::string s_send = td->_this->_handler_request(http_response);
            // std::cout << s_send << std::endl;             //DEBUG
            if (!s_send.empty())
            {
                std::cout << s_send << std::endl;
                td->_socket->Send(s_send);
            }
        }

        td->_socket->CloseSockfd();
        delete td->_socket;
        delete td;
        return nullptr;
    }

    void loop()
    {
        while (true)
        {
            std::string peerip;
            uint16_t peerport;
            Socket *newsockfd = _listensocket->AcceptConnection(&peerip, &peerport);
            if (!newsockfd)
                continue; // 防止空指针解引用
            std::cout << "新链接: sockfd: " << newsockfd->GetSockfd() << " client: " << peerip << ":" << peerport << std::endl;

            pthread_t tid;
            ThreadData *td = new ThreadData(newsockfd, this);
            pthread_create(&tid, nullptr, ThreadRoutine, td);
            // std::cout << "1" << std::endl; //DEBUG
            // sleep(10);
            // newsockfd->CloseSockfd();
        }
    }
    ~TcpServer()
    {
    }

private:
    uint16_t _port;
    Socket *_listensocket;

public:
    func_t _handler_request;
};